import mongoose, { Schema, Document } from 'mongoose';
import bcrypt from 'bcryptjs';

/**
 * 用户角色枚举（保留用于向后兼容）
 */
export enum UserRole {
  ADMIN = 'admin',      // 系统管理员
  OPS = 'ops',          // 运维工程师
  VIEWER = 'viewer',    // 只读用户
}

/**
 * 用户状态枚举
 */
export enum UserStatus {
  ACTIVE = 'active',    // 激活
  INACTIVE = 'inactive', // 未激活
  SUSPENDED = 'suspended', // 已暂停
}

/**
 * 用户组织成员关系
 */
export interface IOrganizationMembership {
  organization: mongoose.Types.ObjectId;
  roles: mongoose.Types.ObjectId[]; // 在该组织中的角色
  joinedAt: Date;
  isActive: boolean;
}

/**
 * 用户团队成员关系
 */
export interface ITeamMembership {
  team: mongoose.Types.ObjectId;
  organization: mongoose.Types.ObjectId;
  role: string; // 'leader' | 'member' | 'viewer'
  joinedAt: Date;
}

/**
 * 用户接口定义
 */
export interface IUser extends Document {
  _id: mongoose.Types.ObjectId;
  username: string;
  email: string;
  password: string;
  fullName: string;
  avatar?: string;

  // 向后兼容的简单角色（已弃用，但保留）
  role: UserRole;
  status: UserStatus;

  // 新的组织和角色系统
  organizations: IOrganizationMembership[]; // 用户所属的组织
  teams: ITeamMembership[]; // 用户所属的团队
  globalRoles: mongoose.Types.ObjectId[]; // 全局角色（系统级）

  // 个人信息
  profile?: {
    phone?: string;
    title?: string; // 职位
    department?: string;
    timezone?: string;
    language?: string;
  };

  // 通知配置
  notifications: {
    email: boolean;
    webhook?: string;  // Webhook URL（如钉钉、企业微信等）
  };

  // 统计数据
  stats: {
    alertsHandled: number;
    ticketsResolved: number;
    lastLoginAt?: Date;
  };

  // 时间戳
  createdAt: Date;
  updatedAt: Date;

  // 方法
  comparePassword(candidatePassword: string): Promise<boolean>;
  toSafeObject(): Partial<IUser>;
  hasPermissionInOrganization(organizationId: string, permissionName: string): Promise<boolean>;
  getRolesInOrganization(organizationId: string): mongoose.Types.ObjectId[];
  isMemberOfOrganization(organizationId: string): boolean;
}

/**
 * 组织成员关系 Schema
 */
const OrganizationMembershipSchema = new Schema<IOrganizationMembership>(
  {
    organization: {
      type: Schema.Types.ObjectId,
      ref: 'Organization',
      required: true
    },
    roles: [{
      type: Schema.Types.ObjectId,
      ref: 'Role'
    }],
    joinedAt: {
      type: Date,
      default: Date.now
    },
    isActive: {
      type: Boolean,
      default: true
    }
  },
  { _id: false }
);

/**
 * 团队成员关系 Schema
 */
const TeamMembershipSchema = new Schema<ITeamMembership>(
  {
    team: {
      type: Schema.Types.ObjectId,
      ref: 'Team',
      required: true
    },
    organization: {
      type: Schema.Types.ObjectId,
      ref: 'Organization',
      required: true
    },
    role: {
      type: String,
      enum: ['leader', 'member', 'viewer'],
      default: 'member'
    },
    joinedAt: {
      type: Date,
      default: Date.now
    }
  },
  { _id: false }
);

/**
 * 用户数据模型
 */
const UserSchema = new Schema<IUser>(
  {
    username: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      minlength: 3,
      maxlength: 50,
      index: true,
    },
    email: {
      type: String,
      required: true,
      unique: true,
      lowercase: true,
      trim: true,
      match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
      index: true,
    },
    password: {
      type: String,
      required: true,
      minlength: 6,
      select: false, // 默认不返回密码字段
    },
    fullName: {
      type: String,
      required: true,
      trim: true,
      maxlength: 100,
    },
    avatar: {
      type: String,
      default: null,
    },
    role: {
      type: String,
      enum: Object.values(UserRole),
      default: UserRole.VIEWER,
      index: true,
    },
    status: {
      type: String,
      enum: Object.values(UserStatus),
      default: UserStatus.ACTIVE,
      index: true,
    },
    organizations: [OrganizationMembershipSchema],
    teams: [TeamMembershipSchema],
    globalRoles: [{
      type: Schema.Types.ObjectId,
      ref: 'Role'
    }],
    profile: {
      phone: String,
      title: String,
      department: String,
      timezone: {
        type: String,
        default: 'UTC'
      },
      language: {
        type: String,
        default: 'en'
      }
    },
    notifications: {
      email: {
        type: Boolean,
        default: true,
      },
      webhook: {
        type: String,
        default: null,
      },
    },
    stats: {
      alertsHandled: {
        type: Number,
        default: 0,
      },
      ticketsResolved: {
        type: Number,
        default: 0,
      },
      lastLoginAt: {
        type: Date,
        default: null,
      },
    },
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

/**
 * 索引定义
 */
UserSchema.index({ email: 1, status: 1 });
UserSchema.index({ role: 1, status: 1 });
UserSchema.index({ createdAt: -1 });
UserSchema.index({ 'organizations.organization': 1 });
UserSchema.index({ 'teams.team': 1 });
UserSchema.index({ 'teams.organization': 1 });
UserSchema.index({ globalRoles: 1 });

/**
 * 保存前钩子：密码加密
 */
UserSchema.pre<IUser>('save', async function (next) {
  if (!this.isModified('password')) {
    return next();
  }

  try {
    const salt = await bcrypt.genSalt(10);
    this.password = await bcrypt.hash(this.password, salt);
    next();
  } catch (error: any) {
    next(error);
  }
});

/**
 * 实例方法：比较密码
 */
UserSchema.methods.comparePassword = async function (
  candidatePassword: string
): Promise<boolean> {
  try {
    return await bcrypt.compare(candidatePassword, this.password);
  } catch (error) {
    return false;
  }
};

/**
 * 实例方法：返回安全的用户对象（不包含敏感信息）
 */
UserSchema.methods.toSafeObject = function (): Partial<IUser> {
  const obj = this.toObject();
  delete obj.password;
  return obj;
};

/**
 * 实例方法：检查用户是否是组织成员
 */
UserSchema.methods.isMemberOfOrganization = function(organizationId: string): boolean {
  return this.organizations.some(
    (org: IOrganizationMembership) => org.organization.toString() === organizationId.toString() && org.isActive
  );
};

/**
 * 实例方法：获取用户在组织中的角色
 */
UserSchema.methods.getRolesInOrganization = function(organizationId: string): mongoose.Types.ObjectId[] {
  const membership = this.organizations.find(
    (org: IOrganizationMembership) => org.organization.toString() === organizationId.toString() && org.isActive
  );
  return membership ? membership.roles : [];
};

/**
 * 实例方法：检查用户在组织中是否有某个权限
 */
UserSchema.methods.hasPermissionInOrganization = async function(
  organizationId: string,
  permissionName: string
): Promise<boolean> {
  const Role = mongoose.model('Role');
  const Permission = mongoose.model('Permission');

  // 获取用户在该组织中的角色
  const roleIds = this.getRolesInOrganization(organizationId);
  if (roleIds.length === 0) {
    return false;
  }

  // 查找角色和权限
  const roles = await Role.find({ _id: { $in: roleIds } }).populate('permissions');
  const permission = await Permission.findOne({ name: permissionName });

  if (!permission) {
    return false;
  }

  // 检查角色是否包含该权限
  for (const role of roles) {
    if (role.permissions.some((p: any) => p._id.toString() === permission._id.toString())) {
      return true;
    }
  }

  return false;
};

/**
 * 静态方法：根据邮箱查找用户（包含密码）
 */
UserSchema.statics.findByCredentials = async function (
  email: string
): Promise<IUser | null> {
  return this.findOne({ email, status: UserStatus.ACTIVE }).select('+password');
};

/**
 * 静态方法：查找组织的所有成员
 */
UserSchema.statics.findByOrganization = function(organizationId: string) {
  return this.find({
    'organizations.organization': organizationId,
    'organizations.isActive': true,
    status: UserStatus.ACTIVE
  });
};

/**
 * 静态方法：查找团队的所有成员
 */
UserSchema.statics.findByTeam = function(teamId: string) {
  return this.find({
    'teams.team': teamId,
    status: UserStatus.ACTIVE
  });
};

export default mongoose.model<IUser>('User', UserSchema);
